package com.deco.back.utils;

import com.free.common.vo.ResultModel;
import com.free.ext.logger.FreeLogger;
import com.free.ext.logger.FreeLoggerFactory;
import com.free.ext.shiro.SessionManager;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.security.KeyPair;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;

/**
 * <p>
 * 功能概述:
 * </p>
 * <p>
 * 功能详述:
 * </p>
 */
public class LoginUtil {
    /*========================================================================*
     *                         Public Fields (公共属性)
     *========================================================================*/

    /*========================================================================*
     *                         Private Fields (私有属性)
     *========================================================================*/

    private static final FreeLogger LOG = FreeLoggerFactory.getLogger(LoginUtil.class);

    /*========================================================================*
     *                         Construct Methods (构造方法)
     *========================================================================*/

    /*========================================================================*
     *                         Public Methods (公有方法)
     *========================================================================*/

    /**
     * 获取公私钥对象初始化
     *
     * @param request
     */
    public static void rsaInit(HttpServletRequest request) {
        try {
            KeyPair kp = RsaUtil.generateKeyPair(); // 获取随机生成的公私钥对象
            RSAPublicKey pubKey = (RSAPublicKey) kp.getPublic(); // 获取RSA的公钥
            String module = pubKey.getModulus().toString(16);
            String exponent = pubKey.getPublicExponent().toString(16);

            request.setAttribute("m", module);
            request.setAttribute("e", exponent);

            RSAPrivateKey privKey = (RSAPrivateKey) kp.getPrivate();
            SessionManager.set("privKey", privKey);
            SessionManager.set("p5", EncryptUtil.encript(privKey.getPrivateExponent().toString(16), "UTF-8"));
        } catch (Exception e) {
            LOG.error("获取公私钥对象异常", e);
        }
    }

    /**
     * 解密密码字段
     *
     * @param
     * @param password
     * @return
     */
    public static ResultModel rsaDecode(String p5, String password) {

        try {
            RSAPrivateKey privKey = (RSAPrivateKey) SessionManager.get("privKey");
            // 判断私钥是否失效。init时存入session，同事放入页面，登陆时判定两处是否一致。
            if (p5.equals(EncryptUtil.encript(privKey.getPrivateExponent().toString(16), "UTF-8"))) {
                byte[] en_result = LoginUtil.hexStringToBytes(password);
                byte[] de_result = RsaUtil.decrypt(privKey, en_result);

                StringBuffer sb = new StringBuffer();
                sb.append(new String(de_result));
                password = sb.reverse().toString();
                return ResultModel.success(password);
            } else {
                return ResultModel.failure();
            }
        } catch (Exception e) {
            LOG.info("私钥解密失败：" + e.getMessage());
            return ResultModel.failure();
        }
    }

    /**
     * 16进制 To byte[]
     *
     * @param hexString
     * @return byte[]
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    /**
     * Convert char to byte
     *
     * @param c
     *            char
     * @return byte
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    /*========================================================================*
     *                         Private Methods (私有方法)
     *========================================================================*/
}
